﻿#define SYNCLOGINFAIL

using System;
using System.Collections.Generic;
using System.Linq;
using YmtAuth.Domain.Model.LoginAuth;
using YmtAuth.Domain.Repository;
using YmtAuth.Dto;
using YmtSystem.CrossCutting;
using YmtAuth.Domain.Shard;
using Ymatou.User.Dto.Auth;
using Ymatou.User.Dto;
using YmtAuth.Domain.Repository.EventRepository;
using YmtAuth.Domain.Model.YmatouUser.Event;
using YmtAuth.LogService;
using YmtAuth.Repository.MSSQL;
using ServiceStack;
using YmtAuth.Domain.Model.Safe;
using YmtAuth.Repository.MySQL;
using System.Configuration;
using YmtAuth.Common;
using YmtAuth.AppService.JavaService;
using ServiceStack.Web;

namespace YmtAuth.AppService
{
    public class LoginSafeAppService : ILoginSafeAppService
    {
        private IUserLoginBillsRepository UlBRepository { get { return LocalServiceLocator.GetService<IUserLoginBillsRepository>(); } }

        /// <summary>
        /// 风控解锁日志仓储实例
        /// </summary>
        private IAuthSafeManageLogRepository authSafeManageRepo { get { return LocalServiceLocator.GetService<IAuthSafeManageLogRepository>(); } }

        /// <summary>
        /// 风控日志仓储实例
        /// </summary>
        private IAuthSafeVerifyLogRepository safeVerifyLogRepo { get { return LocalServiceLocator.GetService<IAuthSafeVerifyLogRepository>(); } }

        private static readonly UserLoginAuthRepository repo = new UserLoginAuthRepository();

        private static readonly IIpAreaInfoRepository IpAreaInfoRepo = new IpAreaInfoRepository();

        private static readonly IUserDeviceAuthRepository deviceRepo = new UserDeviceAuthRepository();

        /// <summary>
        /// 需要身份认证的返回码
        /// </summary>
        private static int[] NeedIdentityAuthCode = { AuthSafeHandleSubCode.NeedIdentityVerify_LanIP, 
                                                     AuthSafeHandleSubCode.NeedIdentityVerify_LoginSafe_LoginPasswordHistoryVerify, 
                                                     AuthSafeHandleSubCode.NeedIdentityVerify_LoginSafe_BlackIPVerify, 
                                                     AuthSafeHandleSubCode.NeedIdentityVerify_LoginSafe_CannotFindIpArea, 
                                                     AuthSafeHandleSubCode.NeedIdentityVerify_LoginSafe_VerifyIPAreaStatus,

                                                     AuthSafeHandleSubCode.NeedIdentityVerify_LoginSafe_VerifyIpAreaLastAuthTime, 
                                                     AuthSafeHandleSubCode.NeedIdentityVerify_LoginSafe_DeviceAndCLientIdNotExists, 
                                                     AuthSafeHandleSubCode.NeedIdentityVerify_LoginSafe_CannotFindDevice,

                                                     AuthSafeHandleSubCode.NeedIdentityVerify_LoginSafe_VerifyDeviceStatus, 
                                                     AuthSafeHandleSubCode.NeedIdentityVerify_LoginSafe_VerifyClientIdStatus};

        /// <summary>
        /// 解锁IP区域只解锁最近更新过的那一条
        /// </summary>
        private static int[] VerifyIPAreaFailCode = { AuthSafeHandleSubCode.NeedIdentityVerify_LoginSafe_CannotFindIpArea, 
                                                     AuthSafeHandleSubCode.NeedIdentityVerify_LoginSafe_VerifyIPAreaStatus, 
                                                     AuthSafeHandleSubCode.NeedIdentityVerify_LoginSafe_VerifyIpAreaLastAuthTime};

        /// <summary>
        /// 查询用户是否风控
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>

        public ResponseData<GetLoginSafeStatusResponseDto> GetLoginSafeStatus(GetLoginSafeStatusRequestDto dto, IRequest request = null)
        {

            if (request != null)
            {
                if (RequestUserService.isSendReadToJavaUserService(dto, "GetLoginSafeStatusRequestDto", "GET", new string[] { dto.LoginName.ToString() }))
                {
                    var r = RequestUserService.sendReadRequest<ResponseData<GetLoginSafeStatusResponseDto>>(dto, "GetLoginSafeStatusRequestDto", request.RawUrl, "GET",
                        request.QueryString);
                    if (r.isRequestSuccess) return r.resp;
                }
            }

            YmtSystemAssert.AssertArgumentNotNull(dto, "无效的GetUserLoginNameRequestDto");
            YmtSystemAssert.AssertArgumentNotEmpty(dto.LoginName, "无效的LoginName");
            ResponseData<GetLoginSafeStatusResponseDto> res = null;

            string loginId = dto.LoginName;
            UserLoginBill userModel = UlBRepository.FindOne(UserLoginAuthSpecifications.MatchLoginId(loginId, false), true);

            GetLoginSafeStatusResponseDto result = new GetLoginSafeStatusResponseDto();
            if (userModel == null)
            {
                res = ResponseData<GetLoginSafeStatusResponseDto>.Create(result, true, "未找到该用户：" + loginId, "100");
            }
            else
            {
                result = new GetLoginSafeStatusResponseDto()
                {
                    LoginId = userModel.LoginBills.LoginId,
                    Mail = userModel.LoginBills.Email,
                    Mobile = userModel.LoginBills.Mobile,
                    UserId = userModel.UserId
                };

                ResponseData<List<SafeVerifyLogEntity>> logRes = safeVerifyLogRepo.GetLastLoginSafeVerifyLog(userModel.UserId, userModel.LoginBills.LoginId, userModel.LoginBills.Mobile, userModel.LoginBills.Email, ConfigUtility.QueryLoginSafeStatusDayConfig);

                if (logRes.Success)
                {
                    List<SafeVerifyLogEntity> list = logRes.Result;
                    if (list != null)
                    {
                        var tempList = list.Where(r => NeedIdentityAuthCode.Contains(r.ResponseCode)).OrderByDescending(r=>r.CreateTime);

                        if (tempList != null)
                        {
                            result.SafeVerifyLogList = tempList.ToList();
                        }
                    }
                    
                    res = ResponseData<GetLoginSafeStatusResponseDto>.Create(result, true, "ok", "200");
                }
                else
                {
                    res = ResponseData<GetLoginSafeStatusResponseDto>.Create(result, false, logRes.LastErrorMessage, logRes.ErrorCode);
                }
            }

            YmatouLoggingService.Debug("查询用户是否风控, GetLoginSafeStatus, LoginName: {0}, code: {1}, LastErrorMessage: {2}", dto.LoginName, res.ErrorCode, res.LastErrorMessage);

            return res;
        }

        /// <summary>
        /// 更新用户指定IP区域认证状态为“已认证”
        /// </summary>     
        public ResponseData<int> AuthIpAreaInfoSuccess(IpAreaAuthManageRequestDto dto, IRequest request = null)
        {

            if (request != null)
            {
                if (RequestUserService.isSendReadToJavaUserService(dto, "IpAreaAuthManageRequestDto", "GET", new string[] { dto.UserId.ToString() }))
                {
                    var r = RequestUserService.sendReadRequest<ResponseData<int>>(dto, "IpAreaAuthManageRequestDto", request.RawUrl, "GET",
                        request.QueryString);
                    if (r.isRequestSuccess) return r.resp;
                }
            }

            YmtSystemAssert.AssertArgumentNotNull(dto, "非法的参数IpAreaAuthManageRequestDto");
            YmatouLoggingService.Debug("AuthIpAreaInfoSuccess, {0}", dto.ToString());

            ResponseData<int> res = null;

            int userId = dto.UserId;
            if (userId <= 0)
            {
                res = ResponseData<int>.Create(-1, false, "非法的用户ID, UserId: " + userId, "100");
            }
            else if (string.IsNullOrEmpty(dto.Country))
            {
                res = ResponseData<int>.Create(-1, false, "Country不能为空", "100");
            }

            else if (string.IsNullOrEmpty(dto.Province))
            {
                res = ResponseData<int>.Create(-1, false, "Province不能为空", "100");
            }

            else if (string.IsNullOrEmpty(dto.City))
            {
                res = ResponseData<int>.Create(-1, false, "City不能为空", "100");
            }
            else
            {
                try
                {
                    // 解锁IP区域只解锁最近更新过的那一条
                    UserLoginBill userModel = UlBRepository.FindOne(UserLoginAuthSpecifications.MatchUserId(userId), true);

                    if (userModel == null)
                    {
                        res = ResponseData<int>.Create(-1, false, "未找到该用户：" + userId, "300");
                    }
                    else
                    {
                        ResponseData<List<SafeVerifyLogEntity>> logRes = safeVerifyLogRepo.GetLastLoginSafeVerifyLog(userModel.UserId, userModel.LoginBills.LoginId, userModel.LoginBills.Mobile, userModel.LoginBills.Email, ConfigUtility.QueryLoginSafeStatusDayConfig);

                        if (logRes.Success)
                        {
                            List<SafeVerifyLogEntity> list = logRes.Result;
                            if (list != null)
                            {
                                var latestIpAreaFail = list.Where(r => VerifyIPAreaFailCode.Contains(r.ResponseCode)).OrderByDescending(r => r.CreateTime).FirstOrDefault();

                                if (latestIpAreaFail != null && !(latestIpAreaFail.UserId == userId && string.Equals(dto.GetArea(), latestIpAreaFail.IpArea, StringComparison.InvariantCultureIgnoreCase)))
                                {
                                    res = ResponseData<int>.Create(-1, false, "解锁IP区域只解锁最近更新过的那一条", "500");
                                }
                            }
                        }
                        else
                        {
                            res = ResponseData<int>.Create(-1, false, logRes.LastErrorMessage, logRes.ErrorCode);
                        }

                        if (res == null)
                        {
                            int affectedRows = IpAreaInfoRepo.AuthIpAreaInfoSuccess(userId, dto.Country, dto.Province, dto.City);

                            res = ResponseData<int>.Create(affectedRows, true, "ok", "200");
                        }
                    }
                }
                catch (Exception ex)
                {
                    res = ResponseData<int>.Create(-1, false, "手动认证IP区域出现异常：" + ex.Message, "400");
                }
            }

            YmatouLoggingService.Debug("客服解锁 IP区域, AuthIpAreaInfoSuccess, userid: {0}, code: {1}, affectedRows: {2}, LastErrorMessage: {3}", dto.UserId, res.ErrorCode, res.Result, res.LastErrorMessage);

            AuthSafeManageLog log = new AuthSafeManageLog()
            {
                OpSource = "servicecenter",
                OpType = "AuthIpAreaInfoSuccess",
                UserId = userId,
                OpParameter = dto.GetArea(),
                ResponseDesc = res.LastErrorMessage,
                CreateTime = DateTime.Now
            };

            authSafeManageRepo.InsertAsync(log, true);

            return res;
        }

        /// <summary>
        /// 更新用户的所有 设备/ClientId 认证状态为“已认证”
        /// </summary>     
        public ResponseData<int> AuthUserDeviceSuccess(DeviceAuthManageRequestDto dto, IRequest request = null)
        {

            if (request != null)
            {
                if (RequestUserService.isSendReadToJavaUserService(dto, "DeviceAuthManageRequestDto", "GET", new string[] { dto.UserId.ToString() }))
                {
                    var r = RequestUserService.sendReadRequest<ResponseData<int>>(dto, "DeviceAuthManageRequestDto", request.RawUrl, "GET",
                        request.QueryString);
                    if (r.isRequestSuccess) return r.resp;
                }
            }

            YmtSystemAssert.AssertArgumentNotNull(dto, "非法的参数DeviceAuthManageRequestDto");

            ResponseData<int> res = null;

            int userId = dto.UserId;
            if (userId <= 0)
            {
                res = ResponseData<int>.Create(-1, false, "非法的用户ID, UserId: " + userId, "100");
            }
            else
            {
                try
                {
                    int affectedRows = deviceRepo.AuthUserDeviceSuccess(userId);

                    res = ResponseData<int>.Create(affectedRows, true, "ok", "200");
                }
                catch (Exception ex)
                {
                    res = ResponseData<int>.Create(-1, false, "手动认证 设备/ClientId 出现异常：" + ex.Message, "400");
                }
            }

            YmatouLoggingService.Debug("客服解锁 设备/ClientId, AuthIpAreaInfoSuccess, userid: {0}, affectedRows: {1}, LastErrorMessage: {2}", userId, res.Result, res.LastErrorMessage);

            AuthSafeManageLog log = new AuthSafeManageLog()
            {
                OpSource = "servicecenter",
                OpType = "AuthUserDeviceSuccess",
                UserId = userId,
                ResponseDesc = res.LastErrorMessage,
                CreateTime = DateTime.Now
            };

            authSafeManageRepo.InsertAsync(log, true);

            return res;
        }

        ///// <summary>
        ///// 查看被风控的用户当前的锁定状态（http://172.16.100.247/zhangtingting/%E4%B9%B0%E6%89%8B%E5%AE%89%E5%85%A8%E4%B8%AD%E5%BF%83/#g=1&p=运营后台解锁功能）
        ///// </summary>
        ///// <param name="safeVerifyLog"></param>
        //private void CheckIsBlocked(SafeVerifyLogEntity safeVerifyLog)
        //{
        //    if (safeVerifyLog == null) return;

        //    //TODO:
        //    safeVerifyLog.IsBlocked = true;
        //    switch (safeVerifyLog.ResponseCode)
        //    {
        //        // 买手本地局域网IP
        //        case AuthSafeHandleSubCode.NeedIdentityVerify_LanIP:
        //            safeVerifyLog.BlockReason = "买手本地局域网IP";
        //            break;
                
        //        // 登录历史密码错误-3分钟内大于等于5
        //        case AuthSafeHandleSubCode.NeedIdentityVerify_LoginSafe_LoginPasswordHistoryVerify:
        //            safeVerifyLog.BlockReason = "登录历史密码错误次数超限";
        //            break;
        //        // IP黑名单
        //        case AuthSafeHandleSubCode.NeedIdentityVerify_LoginSafe_BlackIPVerify:
        //            safeVerifyLog.BlockReason = "IP黑名单";
        //            break;

        //        // IP区域不存在
        //        case AuthSafeHandleSubCode.NeedIdentityVerify_LoginSafe_CannotFindIpArea:
        //        // IP区域状态验证失败
        //        case AuthSafeHandleSubCode.NeedIdentityVerify_LoginSafe_VerifyIPAreaStatus:
        //            safeVerifyLog.BlockReason = "异地登录";
        //            break;

        //        case AuthSafeHandleSubCode.NeedIdentityVerify_LoginSafe_VerifyIpAreaLastAuthTime:
        //            safeVerifyLog.BlockReason = "登录区域认证时间超3个月";
        //            break;

        //        case AuthSafeHandleSubCode.NeedIdentityVerify_LoginSafe_VerifyBlackDevice:
        //            safeVerifyLog.BlockReason = "手机设备号黑名单";
        //            break;

        //        case AuthSafeHandleSubCode.NeedIdentityVerify_LoginSafe_VerifyDeviceStatus:
        //            safeVerifyLog.BlockReason = "手机设备号未认证";
        //            break;

        //        case AuthSafeHandleSubCode.NeedIdentityVerify_LoginSafe_VerifyClientIdStatus:
        //            safeVerifyLog.BlockReason = "客户端号未认证";
        //            break;

        //        case AuthSafeHandleSubCode.NeedIdentityVerify_LoginSafe_CannotFindDevice:
        //            safeVerifyLog.BlockReason = "设备号为空";
        //            break;

        //        case AuthSafeHandleSubCode.NeedIdentityVerify_LoginSafe_DeviceAndCLientIdNotExists:
        //            safeVerifyLog.BlockReason = "设备号，CLientID为空";
        //            break;
        //    }
        //}
    }
}
